package com.aispeech.jarpc;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

@Slf4j
public class EventLoop extends Thread {
    Selector selector;

    public EventLoop(Selector selector) throws IOException {
        setName("arpc-eventloop");
        setDaemon(true);
        this.selector = selector;
    }

    @Override
    public void run() {
//        log.info("EventLoop.run...");

        while (!isInterrupted()) {
            try {
                if (selector.select(100) > 0) {
                    Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();

                    while (keyIterator.hasNext()) {
                        SelectionKey selectionKey = keyIterator.next();

                        SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                        TcpClient client = (TcpClient) selectionKey.attachment();

                        try {
                            if (selectionKey.isConnectable()) {
                                client.onConnected(selectionKey, socketChannel);
                            } else if (selectionKey.isValid() && selectionKey.isReadable()) {
                                client.onReceived(selectionKey, socketChannel);
                            }
                        } catch (Exception e) {
                            log.warn("eventLoop error", e);
                        }

                        keyIterator.remove();
                    }
                } else {
                    Thread.sleep(1);
                }
            } catch (Exception e) {
                log.error("eventLoop error", e);
                break;
            }
        }

        log.warn("jarpc event loop will be stopped!");
    }
}
